﻿// <copyright file="MovieReviewsByKeyword.cs" company="Microsoft Corporation">
// Copyright (c) 2009 Microsoft Corporation All Rights Reserved
// </copyright>
// <author>Michael S. Scherotter</author>
// <email>mischero@microsoft.com</email>
// <date>2009-03-25</date>
// <summary>Summary of this file.</summary>

namespace NYTimes
{
    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.Text;
#if SILVERLIGHT
#else
    using System.Web;
#endif
    using NYTimes.Core;
    using NYTimes.Data;

    /// <summary>
    /// New York Times Movie Reivews by Keywork API
    /// </summary>
    /// <remarks>http://developer.nytimes.com/docs/movie_reviews_api/</remarks>
    public class MovieReviewsByKeyword : MovieReviewBase
    {
        #region Fields
        /// <summary>
        /// the keyword query
        /// </summary>
        private string query;

        /// <summary>
        /// Filter by NYT Critics' picks
        /// </summary>
        private bool? critisPicks;

        /// <summary>
        /// Filter by NYT Thousand best movies
        /// </summary>
        private bool? thousandBest;

        /// <summary>
        /// Specify an order of results
        /// </summary>
        private MovieReviewOrder? order;
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the keyword query
        /// </summary>
        [Description("Specify the keyword query.")]
        public string Query
        {
            get
            {
                return this.query;
            }

            set
            {
                this.query = value;

                this.UpdateResults();
            }
        }

        /// <summary>
        /// Gets or sets a value to limit the results to NYT Critics' Picks. 
        /// </summary>
        [Description("Specify whether to limit the results to critics' picks")]
        public bool? CriticsPicks
        {
            get
            {
                return this.critisPicks;
            }

            set
            {
                if (this.critisPicks != value)
                {
                    this.critisPicks = value;

                    this.UpdateResults();
                }
            }
        }
                
        /// <summary>
        /// Gets or sets the thousand best
        /// </summary>
        [Description("Specify whether to limit the results the NYT list of 1,000 best movies ever made.")]
        public bool? ThousandBest
        {
            get
            {
                return this.thousandBest;
            }

            set
            {
                if (this.thousandBest != value)
                {
                    this.thousandBest = value;

                    this.UpdateResults();
                }
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether to get DVD results
        /// </summary>
        [Description("Specify whether to limit the results to DVD Reviews")]
        public bool? DVD { get; set; }

        /// <summary>
        /// Gets or sets the reviewer's name
        /// </summary>
        [Description("Specify whether to limit the results a specific reviewer")]
        public string Reviewer { get; set; }

        /// <summary>
        /// Gets or sets the publication start date
        /// </summary>
        [Description("Specify the publication start date for the query")]
        public DateTime? PublicationStartDate { get; set; }

        /// <summary>
        /// Gets or sets the publication end date
        /// </summary>
        /// <remarks>must be used with PublicationStartDate</remarks>
        [Description("Specify the publication end date for the query")]
        public DateTime? PublicationEndDate { get; set; }

        /// <summary>
        /// Gets or sets the opening date
        /// </summary>
        [Description("Specify the opening date of the movie")]
        public DateTime? OpeningDate { get; set; }

        /// <summary>
        /// Gets or sets the order
        /// </summary>
        [Description("Specify the sort order")]
        public MovieReviewOrder? Order 
        { 
            get
            {
                return this.order;
            }

            set
            {
                if (this.order != value)
                {
                    this.order = value;

                    this.TriggerPropertyChanged("Order");

                    this.UpdateResults();
                }
            }
        }

        #endregion

        #region Methods
        /// <summary>
        /// Generate the REST URI
        /// </summary>
        /// <returns>a URI for the REST call</returns>
        public override Uri GenerateUri()
        {
            var builder = new StringBuilder("http://api.nytimes.com/svc/movies/v2/reviews/search.xml?");

            builder.AppendFormat(CultureInfo.InvariantCulture, "api-key={0}", this.ApiKey);

            if (!string.IsNullOrEmpty(this.Query))
            {
                builder.AppendFormat(CultureInfo.InvariantCulture, "&query={0}", Uri.EscapeDataString(this.Query));
            }

            AppendLimiter(builder, this.CriticsPicks, "critics-pick");

            AppendLimiter(builder, this.ThousandBest, "thousand-best");

            AppendLimiter(builder, this.DVD, "dvd");

            if (!string.IsNullOrEmpty(this.Reviewer))
            {
                builder.AppendFormat(CultureInfo.InvariantCulture, "&reviewer={0}", this.Reviewer);
            }

            this.AppendOffset(builder);

            if (this.PublicationStartDate.HasValue)
            {
                if (this.PublicationEndDate.HasValue)
                {
                    builder.AppendFormat(
                        CultureInfo.InvariantCulture,
                        "&publication-date={0:yyyy-MM-dd};{1:yyyy-MM-dd}",
                        this.PublicationStartDate.Value,
                        this.PublicationEndDate.Value);
                }
                else
                {
                    builder.AppendFormat(
                        CultureInfo.InvariantCulture,
                        "&publication-date={0:yyyy-MM-dd}",
                        this.PublicationStartDate.Value);
                }
            }

            if (this.OpeningDate.HasValue)
            {
                builder.AppendFormat(
                    CultureInfo.InvariantCulture,
                    "&opening-date={0:yyyy-MM-dd}",
                    this.OpeningDate.Value);
            }

            if (this.Order.HasValue)
            {
                builder.AppendFormat(
                    CultureInfo.InvariantCulture,
                    "&order={0}",
                    MovieReviewBase.ReviewOrderMap[this.Order.Value]);
            }

            return new Uri(builder.ToString(), UriKind.Absolute);
        }

        #endregion
    }
}
